package ServiceRuler

import (
	"encoding/json"
	"log"
	"reflect"
	"strconv"
	"strings"
	"ustcLab/conf"
	"ustcLab/server/common/stringUtils"
	"ustcLab/server/dao/bean"
	"ustcLab/server/dao/daoimpl"
)

/*
	读取规则表所有命中匹配规则进行判断。满足规则表的某一条告警规则，会将该字段加入结果集

返回第一项：
	需要告警的字段列表
返回第二项：
	False: 至少一条规则没有通过
	True：所有规则校验通过
*/
func CheckRuler(monitorInfo *bean.TMonitorInfo) ([]string, []string, bool) {
	res := make([]string, 0)
	resVal := make([]string, 0)

	// 读数据库的规则表判断
	rule, err := daoimpl.GetRuleByName(conf.DefaultRuleName)
	if err != nil {
		log.Println("get rule from database failed! err:", err)
		return res, resVal, true
	}

	var exp *bean.RuleExpression
	err = json.Unmarshal([]byte(rule.FExpression), &exp)
	if err != nil {
		log.Println("rule expression unmarshall failed! err:", err)
		return res, resVal, true
	}

	refType := reflect.TypeOf(*monitorInfo)
	refValue := reflect.ValueOf(*monitorInfo)
	for i := 0; i < refType.NumField(); i++ {
		f := refType.Field(i)
		//如果规则JSON字符串有声明该字段的限制条件，则进入判断流程
		if ruleStr, ok := exp.RuleMap[f.Name]; ok {
			fVal := refValue.Field(i).Float()
			ruleSign := ruleStr[0]
			ruleVal := stringUtils.StrToFloat64(ruleStr[1:])
			if ruleSign == '>' && fVal > ruleVal {
				res = append(res, f.Name)
				resVal = append(resVal, strconv.FormatFloat(fVal, 'f', -1, 64))
			} else if ruleSign == '<' && fVal < ruleVal {
				res = append(res, f.Name)
				resVal = append(resVal, strconv.FormatFloat(fVal, 'f', -1, 64))
			} else if ruleSign == '=' {
				res = append(res, f.Name)
				resVal = append(resVal, strconv.FormatFloat(fVal, 'f', -1, 64))
			}
		}
	}

	// 如果所有规则都匹配
	if len(res) == 0 {
		return res, resVal, true
	}
	return res, resVal, false
}

// 校验传入类型为TDashBoard对象数组的规则检查器
func CheckRuler2(dashBoardInfos []*bean.TDashBoard) ([]string, []string, bool) {
	res := make([]string, 0)
	resVal := make([]string, 0)

	// 读数据库的规则表判断
	rule, err := daoimpl.GetRuleByName(conf.DefaultRuleName)
	if err != nil {
		log.Println("[CheckRuler2]get rule from database failed! err:", err)
		return res, resVal, true
	}

	var exp *bean.RuleExpression
	err = json.Unmarshal([]byte(rule.FExpression), &exp)
	if err != nil {
		log.Println("[CheckRuler2]rule expression unmarshall failed! err:", err)
		return res, resVal, true
	}

	for _, dashBoard := range dashBoardInfos {
		log.Println("[CheckRuler2]rule: ", dashBoard.FName)
		refValue := reflect.ValueOf(*dashBoard)
		fieldValueDataPoints := refValue.FieldByName("FDataPoints").String()
		fValArr := strings.Split(fieldValueDataPoints[1:len(fieldValueDataPoints)-1], ",")
		// 字段内容是{..., offset: value}，即取最后一个数据点的value域
		lastValStr := strings.Split(fValArr[len(fValArr)-1], ":")[1]
		lastVal := stringUtils.StrToFloat64(lastValStr)

		//如果规则JSON字符串有声明该字段的限制条件，则进入判断流程
		if ruleStr, ok := exp.RuleMap[dashBoard.FName]; ok {
			log.Println("[CheckRuler2]ruleStr: ", ruleStr, "; lastVal: ", lastVal)
			ruleSign := ruleStr[0]
			ruleVal := stringUtils.StrToFloat64(ruleStr[1:])
			if ruleSign == '>' && lastVal > ruleVal {
				res = append(res, dashBoard.FName)
				resVal = append(resVal, lastValStr)
			} else if ruleSign == '<' && lastVal < ruleVal {
				res = append(res, dashBoard.FName)
				resVal = append(resVal, lastValStr)
			} else if ruleSign == '=' {
				res = append(res, dashBoard.FName)
				resVal = append(resVal, lastValStr)
			}
		}
	}

	// 如果所有规则都匹配
	if len(res) == 0 {
		return res, resVal, true
	}
	return res, resVal, false
}
